package com.huike.clues.service.impl;

import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;

import com.huike.common.constant.HttpStatus;
import io.minio.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.huike.clues.service.ISysFileService;
import com.huike.common.config.MinioConfig;
import com.huike.common.core.domain.AjaxResult;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService {

    @Autowired
    MinioConfig minioConfig;
    // 日期格式化器，用于生成动态路径
    private static final SimpleDateFormat DATE_FORMATTER = new SimpleDateFormat("yyyy/MM/dd");
    /**
     * 文件上传至Minio
     * 使用try catch finally进行上传
     * finally里进行资源的回收
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
        InputStream inputStream = null;
        MinioClient minioClient = getClient();
        String bucketName = minioConfig.getBucketName();

        try {
            // 1. 校验文件是否为空
            if (file.isEmpty()) {
                return AjaxResult.error("上传文件不能为空");
            }

            // 2. 处理文件信息
            inputStream = file.getInputStream();
            String originalFilename = file.getOriginalFilename();

            // 安全处理原始文件名，防止空指针
            if (originalFilename == null || originalFilename.trim().isEmpty()) {
                originalFilename = "unknown-file";
            }

            // 3. 处理文件后缀
            String suffix = "";
            int lastDotIndex = originalFilename.lastIndexOf(".");
            if (lastDotIndex > 0 && lastDotIndex < originalFilename.length() - 1) {
                suffix = originalFilename.substring(lastDotIndex);
            }

            // 4. 生成新文件名
            String newFileName = UUID.randomUUID().toString() + suffix;

            // 5. 生成动态日期路径（当前日期）
            String datePath = DATE_FORMATTER.format(new Date());
            String objectName = String.format("huike-crm/%s/%s", datePath, newFileName);

            // 6. 检查桶是否存在，不存在则创建
            if (!minioClient.bucketExists(BucketExistsArgs.builder().bucket(bucketName).build())) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(bucketName).build());
                log.info("创建MinIO桶: {}", bucketName);
            }

            // 7. 上传文件到MinIO
            minioClient.putObject(
                    PutObjectArgs.builder()
                            .bucket(bucketName)
                            .object(objectName)
                            .stream(inputStream, inputStream.available(), -1)
                            .contentType(file.getContentType())
                            .build()
            );

            // 8. 构建返回结果（不使用链式put，改为直接put）
            String fileUrl = String.format("http://%s:%d/%s/%s",
                    minioConfig.getEndpoint(),
                    minioConfig.getPort(),
                    bucketName,
                    objectName);

            // 创建成功响应对象
                AjaxResult result = new AjaxResult(HttpStatus.SUCCESS, "操作成功");
            // 直接调用HashMap的put方法添加属性
            result.put("fileName", "/" + objectName);
            result.put("url", fileUrl);

            return result;

        } catch (Exception e) {
            log.error("文件上传失败", e);
            return AjaxResult.error("上传失败: " + e.getMessage());
        } finally {
            // 9. 关闭输入流
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    log.warn("关闭输入流失败", e);
                }
            }
        }
    }

    /**
     * 获取MinIO客户端连接
     *
     * @return MinIO客户端实例
     */
    private MinioClient getClient() {
        return MinioClient.builder()
                .endpoint("http://" + minioConfig.getEndpoint() + ":" + minioConfig.getPort())
                .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                .build();
    }
}
